﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SchoolManagerMVC.BusinessAbstract.Interfaces;
using SchoolManagerMVC.Repository.EntityFramework;
using SchoolManagerMVC.Web.Models;
using System.Web.Security;
using System.Security.Principal;
using SchoolManagerMVC.Web.Areas.Students.ViewModels;
using SchoolManagerMVC.BusinessConcrete.Reporting;

namespace SchoolManagerMVC.Web.Areas.Students.Controllers
{
    [Authorize(Roles=Constants.OfficeAdmin+","+Constants.Admin+","+Constants.Student)]
    public class HomeController : Controller
    {
        /// <summary>
        /// Students Area
        /// </summary>
        private IRepository _repo;
        private IMembership _membership;        

        public HomeController(IRepository repo, IMembership membership)
        {
            _repo = repo;
            if (_repo == null)
                throw new NullReferenceException();

            _membership = membership;
            if (_membership == null)
                throw new NullReferenceException();
        }
        
        public ActionResult Index()
        {
            if (User.IsInRole(Constants.Admin) || User.IsInRole(Constants.OfficeAdmin))
            {
                IEnumerable<Student> result = _repo.GetAll<Student>();
                if(result != null)
                    result = result.ToList().OrderBy(e => e.LastName);
                return View("Index", result);
            }

            else if (User.IsInRole(Constants.Student))
                return View("Details", _membership.getUserID(User.Identity.Name));

            else
                return RedirectToRoute("Default");
        }       
        
        public ActionResult Create()
        {
            if (User.IsInRole(Constants.Admin) || User.IsInRole(Constants.OfficeAdmin))
                return View("Create");
            else
                return RedirectToRoute("Default");
        }
        
        [HttpPost]
        public ActionResult Create([Bind(Exclude="student.UniqueID")] StudentCreationViewModel studentVM)
        {
            if (!User.IsInRole(Constants.Admin) && !User.IsInRole(Constants.OfficeAdmin))
                return RedirectToRoute("Default");

            if (ModelState.IsValid)
            {
                var result =_membership.createUser(studentVM.registerModel.UserName, studentVM.registerModel.Password, studentVM.registerModel.Email);
                if (result == MembershipCreateStatus.Success)
                {
                    _repo.Add<Student>(new Student()
                    {
                        UniqueID = _membership.getUserID(studentVM.registerModel.UserName),
                        FirstName = studentVM.student.FirstName,
                        LastName = studentVM.student.LastName,
                        Age = studentVM.student.Age,
                        TuitionOwed = 0
                    });
                    
                    _membership.addUserToRole(studentVM.registerModel.UserName, Constants.Student);                    
                    return RedirectToRoute("Student_Default");
                }
                else
                {                   
                    ModelState.AddModelError("",MembershipError.ErrorCodeToString(result));
                }                
            }
            return View("Create", studentVM);
        }
        
        public ActionResult Details(Guid id)
        {
           Student result = (Student)_repo.GetSingle<Student>(e => e.UniqueID == id);
           return View("Details",result);
        }
        
        public ActionResult Delete(Guid id)
        {
            if (!User.IsInRole(Constants.Admin) && !User.IsInRole(Constants.OfficeAdmin))
                return RedirectToRoute("Default");

            return View("Delete",_repo.GetSingle<Student>(e => e.UniqueID == id));
        }

        [HttpPost]
        public ActionResult ConfirmDelete(Student student)
        {
            if (!User.IsInRole(Constants.Admin) && !User.IsInRole(Constants.OfficeAdmin))
                return RedirectToRoute("Default");

            var message = _repo.Remove<Student>((_repo.GetSingle<Student>(e => e.UniqueID == student.UniqueID) as Student));

            if(message.result)
                return RedirectToAction("Index");

            ViewBag.Message = message.Message;
                return View("Delete", _repo.GetSingle<Student>(e => e.UniqueID == student.UniqueID));
        }

        public ActionResult Edit(Guid id)
        {
            if (!User.IsInRole(Constants.Admin) && !User.IsInRole(Constants.OfficeAdmin))
                return RedirectToRoute("Default");

            var result = _repo.GetSingle<Student>(e => e.UniqueID == id) as Student;
            if (result == null)
                return RedirectToAction("Index");

            return View("Edit", result);
        }

        [HttpPost]
        public ActionResult Edit(Student student)
        {
            if (!User.IsInRole(Constants.Admin) && !User.IsInRole(Constants.OfficeAdmin))
                return RedirectToRoute("Default");

            if (ModelState.IsValid)
            {
                try
                {
                    var result = _repo.GetSingle<Student>(e => e.UniqueID == student.UniqueID) as Student;
                    mapToStudent(ref result, student);
                    _repo.Update<Student>(result);
                    ViewBag.Message = "Record Saved";
                    return RedirectToAction("Details", new { id = student.UniqueID });
                }
                catch
                {
                    ViewBag.Message = "There was an error saving";
                }
            }
            return View("Edit", student);
        }

        private void mapToStudent(ref Student result, Student student)
        {
            result.FirstName = student.FirstName;
            result.LastName = student.LastName;
            result.Age = student.Age;
            result.TuitionOwed = student.TuitionOwed;
        }

        /*
        [HttpPost]
        public ActionResult MultiDelete(Guid[] selectedItems)
        {
            if(selectedItems == null)
                return RedirectToAction("Index");

            if (selectedItems.Count() > 0)
            {

                foreach (var curr in selectedItems)
                {
                    _repo.Remove<Student>(_repo.GetSingle<Student>(e => e.UniqueID == curr) as Student);
                }
            }

            return RedirectToAction("Index");
        }

        
         * 
         * */
    }
}
